package com.struts2.gae.dispatcher;

import org.apache.struts2.dispatcher.Dispatcher;
import org.apache.struts2.dispatcher.ng.ExecuteOperations;
import org.apache.struts2.dispatcher.ng.HostConfig;
import org.apache.struts2.dispatcher.ng.InitOperations;
import org.apache.struts2.dispatcher.ng.PrepareOperations;
import org.apache.struts2.dispatcher.ng.filter.FilterHostConfig;
import org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter;

import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * GaeFilterDispatcher is an {@link org.apache.struts2.dispatcher.FilterDispatcher} which is specific to Google App Engine.
 * Google App Engine imposes lots of restriction such as you cannot write to the FileSystem. To
 * overcome these restrictions you need to use GaeFilterDispatcher.
 * It overrides createDispatcher method to provide Google App Engine Specific Dispatcher {@link com.struts2.gae.dispatcher.GaeDispatcher}.
 * To use this you need to configure this in your web.xml file instead of {@link org.apache.struts2.dispatcher.FilterDispatcher}.
 *
 * @author whyjava7@gmail.com
 * @version 0.1
 */
@SuppressWarnings("deprecation")
public class GaeFilterDispatcher2
        extends StrutsPrepareAndExecuteFilter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        InitOperations init = new InitOperations() {
            @Override
            public Dispatcher initDispatcher(HostConfig filterConfig) {
                Dispatcher dispatcher = createDispatcher(filterConfig);
                dispatcher.init();
                return dispatcher;
            }

            private Dispatcher createDispatcher(HostConfig filterConfig) {
                Map<String, String> params = new HashMap<String, String>();
                for (Iterator e = filterConfig.getInitParameterNames(); e.hasNext();) {
                    String name = (String) e.next();
                    String value = filterConfig.getInitParameter(name);
                    params.put(name, value);
                }
                return new GaeDispatcher(filterConfig.getServletContext(), params);
            }
        };

        try {
            FilterHostConfig config = new FilterHostConfig(filterConfig);
            init.initLogging(config);
            Dispatcher dispatcher = init.initDispatcher(config);
            init.initStaticContentLoader(config, dispatcher);

            prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher);
            execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher);
            this.excludedPatterns = init.buildExcludedPatternsList(dispatcher);

            postInit(dispatcher, filterConfig);
        } finally {
            init.cleanup();
        }
    }
}
